message(0xd07f6489) InternalInit {
    price: Int;
    reverse: Int as coins;
}

message(0x25938561) Swap {
    query_id: Int as uint64;
    amount: Int as coins;
    from: Address;
}

message(0x71141450) Payto {
    query_id: Int as uint64;
    id: Int;
    amount: Int as coins;
    to: Address;
}

struct PoolData {
    id: Int;
    price: Int;
    reverseA: Int;
}

contract Pool {
    router: Address;
    id: Int;
    price: Int?;
    reverseA: Int?;
    init(router: Address, id: Int) {
        self.router = router;
        self.id = id;
        self.price = null;
        self.reverseA = null;
    }
    
    receive(msg: InternalInit) {
        nativeThrowUnless(71, sender() == self.router);
        self.price = msg.price;
        self.reverseA = msg.reverse;
    }
    
    receive(msg: Swap) {
        let ctx: Context = context();
        nativeThrowUnless(71, ctx.sender == self.router);
        let amountA = msg.amount * self.price!! / 100_000_000;
        // 储备不足
        nativeThrowIf(72, self.reverseA!! < amountA );
        self.send_final_msg(msg.query_id, amountA, msg.from);
    }
    
    fun send_final_msg(query_id: Int, amount: Int, from: Address) {
        send(SendParameters {
            to: self.router,
            value: 0,
            bounce: false,
            mode: SendRemainingBalance | SendDestroyIfZero,
            body: Payto {
                query_id: query_id,
                id: self.id,
                amount: amount,
                to: from,
            }.toCell()
        });
    }
    
    get fun poolData(): PoolData {
        return PoolData{
            id: self.id,
            price: self.price!!,
            reverseA: self.reverseA!!,
        }
    }
}
